/*
	-- 基于jQuery(1.7)扩展插件 autofocus --
author : _米
create : 2011.12.05
update : 2012.07.06
-- 接口说明 --
	- autofocus {Function} #2011.12.05# --此方法实现 tabs
	- @Param options {Object} --总体配置{
			offset : 偏移值，实际scrollTop 和 目标的 offsetTop 的偏移值，默认 0,
			buffer : true, --是否开启缓冲,
			toggleHash : {Boolean} --动画完成后时候在地址栏显示HASH值, 默认 false
			focusClass : 获得焦点时的className - 默认 focus,
			bufferOffset : {Number} --缓冲偏移值 100,
			bufferDuration : {Number} -- 动画事件，默认 320，单位 ms
		}
	- @return {jQuery}
-- 接口说明 end --
*/
(function(global, document, $, undefined){
	var 
	view = $(global),
	_ops = {
		offset : 0,
		buffer : true,
		toggleHash : false,
		focusClass : 'focus',
		bufferOffset : 100,
		bufferDuration : 320
	},
	_noop = function(){},
	_setTop = function(y, x){
		global.scrollTo(isFinite(x) ? x : 0, y);
	},
	scrollTo = (function(){
		var 
		_duration = 480,
		fxEase = function(t){return (t*=2)<1?.5*t*t:.5*(1-(--t)*(t-2));};
		return function(top, callback, duration){
			if(!isFinite(top)) return;
			var 
			tMark = new Date(),
			currTop = view.scrollTop(),
			currLeft = view.scrollLeft(),
			height = top - currTop,
			fx = function(){
				var tMap = new Date() - tMark;
				if(tMap >= duration){
					_setTop(top, currLeft);
					return callback.call(this, top);
				}
				_setTop(currTop + height * fxEase(tMap/duration), currLeft);
				setTimeout(fx, 16);
			};
			callback = $.type(callback) === 'function' ? callback : _noop;
			duration = isFinite(duration) && duration > 0 ? duration : _duration;
			fx();
		};
	})();
	$.fn.autofocus = function(ops){
		//初始化配置
		var 
		self = this,
		len = 0,
		tMark = 0,
		items = [],
		prevInx = -1,
		blurItem = function(inx){
			var item = items[inx];
			if(inx === prevInx){
				prevInx = -1;
			}
			item && item.trigger.removeClass(ops.focusClass);
		},
		focusItem = function(inx){
			var item = items[inx];
			if(item && inx !== prevInx){
				blurItem(prevInx);
				item.trigger.addClass(ops.focusClass);
				prevInx = inx;
			}
		},
		_getOffset = function(elem, offset){
			return elem.offset().top - offset;
		},
		_scrollHandler = function(){
			if(!!_preventScroll) return (_preventScroll = false);
			for(var i=0, top = view.scrollTop(); i<len; i++){
				if(top >= items[i].offset){
					focusItem(i);
					break;
				}
			}
			i >= len && blurItem(prevInx);
		},
		_timer, _preventScroll,
		scrollHandler = function(){
			clearTimeout(_timer);
			!_preventScroll && (_timer = setTimeout(_scrollHandler, 160));
			_preventScroll = false;
		},
		_buildScrollFn = function(inx){
			return function(e){
				e.preventDefault();
				if(inx === prevInx) return;
				var 
				item = items[inx],
				offset = item.offset = _getOffset(item.target, ops.offset);
				if(!ops.buffer){
					global.location.hash = '#' + id;
					return _setTop(offset, view.scrollLeft());
				}
				_setTop(offset + (view.scrollTop() > offset ? ops.bufferOffset : -ops.bufferOffset), view.scrollLeft());
				return scrollTo(offset, function(){
					_preventScroll = true;
					focusItem(inx);
				}, ops.bufferDuration);
			};
		};
		ops = ops || {};
		for(var k in _ops){
			ops[k] === undefined && (ops[k] = _ops[k]);
		}
		view.one('load', function(){
			var inx = -1;
			self.each(function(i){
				var target,
				trigger = self.eq(i),
				id = this.href.slice(this.href.lastIndexOf('#') + 1);
				if(id && (target = $('#' + id)).length){
					items[++inx] = {
						id : id,
						index : inx,
						target : target,
						trigger : trigger,
						offset : _getOffset(target, ops.offset)
					};
				}
			});
			len = items.length;
			items.sort(function(a, b){ return b.offset - a.offset;});							//Order By DESC
			view.scroll(scrollHandler) && setTimeout(_scrollHandler, 320);						//首次延迟执行，保证IE能拿到正确的 scrollTop
			$.each(items, function(inx){ items[inx].trigger.click(_buildScrollFn(inx));});		//Bind Click	
		});
	}
})(this, this.document, jQuery);